﻿#Requires AutoHotkey v2.0

class CustomFs {
  __New(path) {
    this.path := path
    this.m := Map()
  }

  Init() {
    f := FileOpen(this.path, 'r', 'utf-8')
    while lt := f.ReadLine() {
      if lt ~= '^#'
        continue
      if lt ~= '.*:$' {
        list := Array()
        kl := SubStr(lt, 1, StrLen(lt) - 1)
        if this.m.Has(kl)
          throw Error('duplicate key -> ' kl)
        while (slt := f.ReadLine()) ~= '^-' {
          list.Push(LTrim(SubStr(slt, 2)))
          fpos := f.Pos
        }
        this.m.Set(kl, list)
        f.Pos := fpos
      } else {
        kp := InStr(lt, ':')
        k := SubStr(lt, 1, kp - 1)
        if this.m.Has(k)
          throw Error('duplicate key -> ' k)
        v := SubStr(lt, kp + 1)
        this.m.Set(k, v)
      }
    }
    f.Close()
  }

  Update() {
    if this.m.Count = 0
      check := MsgBox('empty data, continue?', , 0x1)
    if check != 'ok'
      return
    f := FileOpen(this.path, 'r', 'utf-8')
    text := ''
    while lt := f.ReadLine() {
      if lt ~= '^#' {
        text .= lt '`n'
        continue
      }
      if lt ~= '.*:$' {
        kl := SubStr(lt, 1, StrLen(lt) - 1)
        if !this.m.Has(kl) {
          while (slt := f.ReadLine()) ~= '^-' {
            fpos := f.Pos
          }
          f.Pos := fpos
          continue
        }
        text .= lt '`n'
        vl := this.m.Get(kl)
        for vi in vl {
          text .= '-' vi '`n'
        }
      } else {
        kp := InStr(lt, ':')
        k := SubStr(lt, 1, kp - 1)
        if !this.m.Has(k)
          continue
        v := this.m.Get(k)
        text .= k ':' v '`n'
      }
    }
    f.Close()
    fw := FileOpen(this.path, 'w', 'utf-8')
    fw.Write(text)
    fw.Close()
  }

  Set(k, v) {
    this.m.Set(k, v)
  }

  Get(k) {
    return this.m.Get(k)
  }
}

if A_LineFile == A_ScriptFullPath {
  path := A_ScriptDir '\test.txt'
  cfs := CustomFs(path)
  cfs.Init()
  cfs.Set('cache', 'abc')
  cfs.Set('group', Array('default1', 'newGroup2'))
  cfs.Update()
}